package com.cloudansys.core.util;

import com.alibaba.fastjson.JSON;
import com.cloudansys.core.cache.CacheManager;
import com.cloudansys.core.constant.Const;
import com.cloudansys.core.entity.MultiDataEntity;
import com.cloudansys.hawkeye.modules.settings.model.vo.PrimaryWarn;
import lombok.extern.slf4j.Slf4j;
import redis.clients.jedis.Jedis;

import java.util.*;

@Slf4j
public class WarnUtil {

    /**
     * 判断是否产生告警
     */
    public static List<PrimaryWarn> judgeWarn(Jedis jedis, MultiDataEntity multiDataEntity) {
        List<PrimaryWarn> warnList = new ArrayList<>();
        String projectId = multiDataEntity.getProjectId();
        String targetType = multiDataEntity.getTargetType();
        String pickTime = CustomDateUtil.trimMilliToStdSec(multiDataEntity.getPickTime());
        String serialCode = multiDataEntity.getSerialCode();
        Double[] values = multiDataEntity.getValues();
        for (int i = 0; i < values.length; i++) {

            // 指标的id和数值
            double quotaValue = values[i];
            double rawQuotaValue = values[i];
            String quotaId = String.valueOf(i + 1);

            // 构造缓存中阈值告警信息的 key，获取所对应的告警等级集合
            String cacheKey = StrUtil.stringsToStr(Const.BAR_BOTTOM, projectId, serialCode, quotaId);
            List<PrimaryWarn> warnLevelList = CacheManager.getWarnLevelList(cacheKey);
//            log.info("============cacheKey: {}", cacheKey);

            if (warnLevelList != null && warnLevelList.size() != 0) {
                // 振动类型阈值告警只有一个等级告警(三级告警)
                if (targetType.equals(Const.TT_ZD)) {
                    PrimaryWarn primaryWarn = warnLevelList.get(0);
                    // 获取振动类型的最大值和最小值
                    double maxTh = Double.parseDouble(jedis.get(Const.ZD_TH_MAX + serialCode));
                    double minTh = Double.parseDouble(jedis.get(Const.ZD_TH_MIN + serialCode));
//                    log.info("================quotaValue: {}", quotaValue);
                    // 根据当前数值的正负判断
                    if (quotaValue > maxTh || quotaValue < minTh) {
                        // 设置告警推送的时间
                        primaryWarn.setTime(new Date());
                        // 设置产生告警的数据时间
                        primaryWarn.setDataTime(pickTime);
                        // 设置告警值
                        primaryWarn.setDataValue(rawQuotaValue);
                        // 设置原始数据
                        primaryWarn.setRawData(values);
                        // 这里把 sc 作为 targetId
                        primaryWarn.setTargetId(Integer.parseInt(serialCode));
                        // 振动告警3秒内连续产生告警则发出告警
                        String warnKey = Const.ZD_WARN + serialCode;
                        String zd_warn = jedis.get(warnKey);
                        jedis.set(warnKey, JSON.toJSONString(primaryWarn));
                        jedis.expire(warnKey, 3);
                        if (zd_warn != null) {
                            warnList.add(primaryWarn);
                        }

                        // 这里只有一个指标
                        break;
                    }
                } else {
                    // 判断指标的数值在哪一个等级范围
                    for (PrimaryWarn primaryWarn : warnLevelList) {
                        Double lower = primaryWarn.getLower();
                        Double upper = primaryWarn.getUpper();
                        Boolean absolute = primaryWarn.getAbsolute();
                        // 判断是否是绝对值
                        if (absolute) {
                            quotaValue = Math.abs(quotaValue);
                        }
                        if (quotaValue > lower && quotaValue < upper) {
                            // 设置告警推送的时间
                            primaryWarn.setTime(new Date());
                            // 设置产生告警的数据时间
                            primaryWarn.setDataTime(pickTime);
                            // 设置告警值
                            primaryWarn.setDataValue(rawQuotaValue);
                            // 设置原始数据
                            primaryWarn.setRawData(values);
                            // 这里把 sc 作为 targetId
                            primaryWarn.setTargetId(Integer.parseInt(serialCode));
                            warnList.add(primaryWarn);

                            // 每个指标只产生一个等级的告警，且产生一级告警后不再产生二等级告警
                            break;
                        }
                    }
                }
            }
        }
        // 只返回一个告警，有一级告警返回一级告警
        if (warnList.size() != 0) {
            for (PrimaryWarn primaryWarn : warnList) {
                if (primaryWarn.getLevel() == 1) {
                    return Collections.singletonList(primaryWarn);
                }
            }
            return Collections.singletonList(warnList.get(0));
        }
        return warnList;
    }

}
